﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace RegExStudy
{
    /// <summary>
    /// 回溯引用：前后一致匹配
    /// </summary>
    public class Chapter8
    {
        /// <summary>
        /// 回溯引用匹配
        /// </summary>
        public void Check1()
        {
            // 先看个 html 的例子
            string str = "<body>  <h1>z1111</h1>  <h2>222ffff</h2>  <h3>6666</h2> </body>";

            var arry = Regex.Matches(str, @"<[Hh][1-6]>.*?</[Hh][1-6]>");
            Console.WriteLine(string.Format("Check1 查询 文本 \n {0} \n匹配字符 {1} ", str, @"\w+@\w+\.\w+"));
            // 虽然看起来是基本能匹配上，但是会有个不正确的 <h3></h2>  因为前后数字并没有要求到一样，而是任意的1-6的数字
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();

            // 使用回溯  \1  ->  \n    n 为数字
            // <[Hh]([1-6])>.*?</[Hh]\1>  和前面相比  [1-6] 变成了子表达式 ([1-6]),  结尾的[1-6] 变成了 \1
            // \1 在这里表示，这里匹配使用的是前面的第一个表达式，即使用第一个表达式匹配上的对应的内容

            arry = Regex.Matches(str, @"<[Hh]([1-6])>.*?</[Hh]\1>");
            Console.WriteLine(string.Format("Check1 查询 文本 \n {0} \n匹配字符 {1} ", str, @"\w+@\w+\.\w+"));
            // 虽然看起来是基本能匹配上，但是会有个不正确的 <h3></h2>  因为前后数字并没有要求到一样，而是任意的1-6的数字
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();

            // 问题：但是如果子表达式有多个，且发生位置变化 \number  的使用就会有问题
            // 有些语法允许给子表达式命名，那么使用回溯的时候可以直接使用名字，就不会有这样的问题（c#道理是可以的）
        }

        /// <summary>
        /// 回溯引用在替换操作中的应用
        /// </summary>
        public void Check2()
        {
            // 正则表达式除了普通的查找，还能做替换(主要就是为了替换学的)
            string str = "hello, ben@163.com is my email address. ";

            // 将文本中的邮箱替换成可点击的链接
            // -> <a herf="mailto:邮箱地址">邮箱地址</a>

            // \w+[\w\.]@[\w\.]+\.\w+ 是之前用来匹配邮箱的，加上() 后变成了子表达式，这个时候被匹配到的文本就可以用在替换模式里了
            // $1  则表示使用匹配到的第一个内容，替换到当前位置
            var arry = Regex.Replace(str, @"(\w+[\w\.]@[\w\.]+\.\w+)","<a herf=\"mailto:$1\">$1</a>");
            Console.WriteLine("Check2 替换文本");
            Console.WriteLine(string.Format("替换前的文本 {0}", str));
            Console.WriteLine(string.Format("替换后的文本 {0}", arry));

            Console.WriteLine();
            // 还有些具体的元字符使用自己看下书或者查下
        }
    }
}
